/**
 * @file envFactory.c
 * @brief Sorgente per la gestione dell'invocazione dei comandi.
 *
 * Prima di gestire una richiesta bisogna gestire l'interfacciamento e l'inizializzazione del sistema
 * di gestione dei comandi. Vengono implementate in questo file le funzioni pubbliche che permettono
 * di configurare correttamente l'inizializzazione dell'invoker e che permettano una corretta interpretazione
 * delle richieste dell'utente.
 * In quest'ultimo caso si devono gestire tramite il pattern chain of responsability le impostazioni per
 * l'interpretazione multipla dei comandi (es: comando exit intepretato anche con 'quit' o con 'q' ecc..).
 *
 * @date Feb 27, 2012
 * @author Francesco Corvino
 */
#include <signal.h>					/** libreria per impostare i segnali gestiti dall IH */
#include "envFactory.h"
#include "applicationLib.h"
#include "../RscApp/rscApplication.h"
#include "../logproxy/logproxy.h"

static EnvFactory* config;

/**
 * @brief costruisce le impostazioni di default dell'applicazione.
 */
void _envFact_initialize(){
	RscApp_init();

	// default values for invoker object
	Invoker *ivk = &(config->invokeconfig);
	ivk->addHistory = NULL;
	Invoke_setInvoker(ivk);

	// default values for inputhandler object
	InputHandler *ih = &(config->inputconfig);
	ih->isConfigurable = 1;
	ih->isLoop = 1;
	ih->timeToWaitInput.tv_sec = 1000;
	ih->timeToWaitInput.tv_usec = 0;
	sigfillset(&(ih->setInputSignals)); // prende tutti i segnali
	ih->updateSignal = SIGUSR1;
	DynArray_init(&(ih->requestfilters),NULL,sizeof(InputFilter));

	// inizializza le comunicazioni
	FactoryComm* fc = &(config->commconfig);
	FactComm_init(fc);
	fc->enableDefaultComm = 1;
}

/**
 * @brief Aggiunge un comando al registro dei comandi.
 *
 * Funzione di inizializzazione e di aggiornamento runtime del programma.
 * Permette di modificare la lista dei comandi conosciuti, viene aggiunto
 * il comando passato a parametro.
 *
 * @param cmd puntatore al comando da aggiungere in memoria.
 * @return -1 se le operazioni non hanno avuto successo.
 */
int envFact_registerCMD(InterfaceCommand * cmd){
	int ret =0;
	DynArray *commands = RscApp_getCommands();
	int numcmd = commands->numelement;
	log_level(LOG_INFO_LEVEL, "ci sono %d comandi all'interno dell'applicativo",numcmd);
	if(DynArray_get(commands, cmd)!=NULL){
		//elemento già registrato
		ret = -1;
	} else RscApp_addCommand(cmd);
	return ret;
}

/**
 * @brief Imposta le configurazioni dell'ambiente d'esecuzione
 */
void envFact_start(){
	// carica le impostazioni di default se non sono state inizializzate
	if(config == NULL ) _envFact_initialize();
	// avvia le comunicazioni
	FactComm_start(&(config->commconfig));
	// aggiorna InputHandler
	IH_setConfiguration(&(config->inputconfig));
    // avvia l'esecuzione
    IH_waitAnInput();
}

void envFact_init(EnvFactory *ptrconfig){
	config = ptrconfig;
	_envFact_initialize();
	// inserire tutte le librerie di base da caricare
	cutility_LoadAllCommands(); // libreria utilità
	testsdlib_LoadAllCommands(); // libreria testing
}
